//
//  Page.m
//  AifudaoDrawer
//
//  Created by Ji Hu on 12-5-16.
//  Copyright (c) 2012年 爱辅导. All rights reserved.
//

#import "Page.h"
#import "Log.h"
#import "DCGlobal.h"

@implementation Page

@synthesize pageNum;

//private
-(void)drawPath:(UIBezierPath*)temppath withColor:(CGColorRef)color{
    
//    CGSize cs = {1, 1};
//    CGContextSetShadow(mContext, cs, 0.5);
    
    CGContextBeginPath(mContext);
    CGContextAddPath(mContext, temppath.CGPath);
    CGContextSetStrokeColorWithColor(mContext, color);
    CGContextDrawPath(mContext, kCGPathStroke);
}

//-(void)drawHoldPath{
//    
//    if (attachedContainer==nil || [attachedContainer isKindOfClass:[PageContainer class]] == NO) {
//        NSLog(@"attached containner wrong or attachedContainer is nil.");
//        return;
//    }
//    
//    NSMutableDictionary *dic = [attachedContainer getPathHolders:self];
//    
//    if (dic == nil) {
//        NSLog(@"do not contains hold path at 'page %d'",self.pageNum);
//        return;
//    }
//    
//    NSLog(@"draw hold path at %d",self.pageNum);
//    
//    NSEnumerator *colors = [dic keyEnumerator ];
//    
//    for(id co in colors){
//        
//        if([co isKindOfClass:[NSNumber class]]){
//            NSNumber *col = co;
//            
//            DispatchPathHolder *th = [dic objectForKey:col];
//            
//            UIBezierPath *path = th.path;
//            
//            [path applyTransform:CGAffineTransformMakeTranslation(0, - self.frame.origin.y)];
//            
//            [self drawPath:path withColor:[attachedContainer.listColor getUIColorByIndex:th.color]];
//            
//            isDirty = YES;
//            
//        }
//        
//    }
//    
//    [dic removeAllObjects];
//}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        self.backgroundColor=[UIColor clearColor];
    }
    return self;
}

//-(int)copyArea:(void *)pixel withArea:(IntRect)dstRect withOffset:(int)offset direction:(BOOL)fromto{
////    CGRect theframe = [FudaoUtil ToCGRect:dstRect];
////    CGRect intersectRactRect = CGRectIntersection([FudaoUtil ToCGRect:dstRect], self.frame) ;
//    dstRect =[FudaoUtil IntRectInsection:dstRect withRect:[FudaoUtil ToIntRect:self.bounds ]];
//    
//    int sWidth=CGImageGetWidth(mContent);
//    int sHeight=CGImageGetHeight(mContent);
//    
//    int bytesPerPixel = 4;
//    int bytesPerRow = sWidth*bytesPerPixel;
//    int width = dstRect.right - dstRect.left + 1;
//    int bytesPerRowInDest = width*bytesPerPixel;
//    
////    NSLog(@"dstRect: %d %d %d %d ",dstRect.left,dstRect.top,dstRect.right,dstRect.bottom);
//    if (fromto) {
//        for (int r = sHeight - 1 - dstRect.bottom, dr = 0 ; r <=  sHeight - 1 - dstRect.top ; r++, dr++) { // upside
//             memcpy(pixel + dr*bytesPerRowInDest+offset, data + r*bytesPerRow + dstRect.left*bytesPerPixel, bytesPerRowInDest);
//        }
//    }else {
//        
//        for (int r = sHeight - 1 - dstRect.top, dr = 0 ; r >= sHeight - 1 - dstRect.bottom ; r--, dr++) {
//            memcpy(pixel + dr*bytesPerRowInDest+offset, data + r*bytesPerRow + dstRect.left*bytesPerPixel, bytesPerRowInDest);
//        }
//    }
//    
//    return (dstRect.bottom - dstRect.top + 1)*bytesPerRowInDest;
//}

//-(BOOL)dispatchImage:(CGImageRef)pixel theSrc:(IntRect)srcRect toRect:(IntRect)destRect{
//    
//    if (isLoading) {
//        [Log warning:@"page is loading."];
//        return NO;
//    }
//    
//    isDirty=YES;
//    
//    //if page num > 0 , it is used in PageContainer.other wise used in dockview.
//    if ([self pageNum]>0) {
//        CGRect toRect = CGRectOffset([FudaoUtil ToCGRect:destRect], 0, -self.frame.origin.y);
//        CGContextDrawImage(mContext, toRect, pixel);
//    }else {
//         CGContextDrawImage(mContext, [FudaoUtil ToCGRect:destRect], pixel);
//    }
//    
//    [self setNeedsDisplay];
//    
//    return YES;
//}

//-(BOOL)dispatchPDF:(CGPDFPageRef)pdfpage theSrc:(IntRect)srcRect toRect:(IntRect)destRect{
//    
//    if (isLoading) {
//        [Log warning:@"page is loading."];
//        return NO;
//    }
//    
//    isDirty = YES;
//    
//    CGContextRef context = mContext;
//    int width = self.bounds.size.width;
//    int height = self.bounds.size.height;
//    
//    CGContextSaveGState(context);
//    
//    CGContextTranslateCTM(context, 0.0, height);
//    CGContextScaleCTM(context, 1.0, -1.0);
//    
//    CGAffineTransform pdfTransform = CGPDFPageGetDrawingTransform(pdfpage, kCGPDFCropBox, CGRectMake(0, 0, width, height), 0, true);
//    CGContextConcatCTM(context, pdfTransform);
//    
//    CGContextDrawPDFPage(context, pdfpage);
//    CGContextRestoreGState(context);
//    
//    return YES;
//}

-(BOOL)dispatchPath:(UIBezierPath *)path withColor:(UIColor *)color{
    
    if (isLoading) {
        return NO;
    }
    
    UIBezierPath *temppath=[path copy];
    
    if ([self pageNum]>0) {
        int dx=0;
        int dy=-self.frame.origin.y;
        [temppath applyTransform:CGAffineTransformMakeTranslation(dx, dy)];
    }
    
    [self drawPath:temppath withColor:color.CGColor];
    
//    [self setNeedsDisplayInRect:CGRectMake(temppath.bounds.origin.x, temppath.bounds.origin.y, temppath.bounds.size.width, temppath.bounds.size.height)];

    [self setNeedsDisplay];
    
    [temppath release];
    
    isDirty=YES;
    
    return YES;
    
}

-(void)setPage:(int)pagenum {
    
    data= NULL;
    datalenth=-1;
    self.pageNum=pagenum;
    [self setTag:pageNum];
    
    isLoading=YES;
    isDirty=NO;
    
//    attachedContainer = container;
}

static void ContentReleaseCallBack(void *info, const void *data, size_t size){
    free(info);
}


// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
//    NSLog(@"draw page:%f %f %f %f",rect.origin.x,rect.origin.y,rect.size.width,rect.size.height);

    // Drawing code
    CGContextRef context=UIGraphicsGetCurrentContext();
    
    if(isLoading){
        CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
        CGContextFillRect(context, CGRectMake(0, 0, self.frame.size.width, self.frame.size.height));
    }
    
    CGContextDrawImage(context, self.bounds, mContent);
    
    if(self.pageNum>0){
        //draw page num text.
        CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0);
        CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);
        CGContextSetTextMatrix(context, CGAffineTransformMakeScale(1.0, -1.0));
        CGContextSelectFont(context, "Helvetica", 18.0, kCGEncodingMacRoman);
        CGContextSetTextDrawingMode(context, kCGTextFill);
        char pageNumStr[16];
        sprintf(pageNumStr, "- %d -", pageNum);
        CGContextShowTextAtPoint(context, self.bounds.size.width-80, self.bounds.size.height-15, pageNumStr, strlen(pageNumStr));
    }
    
    if(isLoading){
        char *loading="Loading...";
        CGContextShowTextAtPoint(context, self.bounds.size.width/2-50, self.bounds.size.height/2-15, loading, strlen(loading));
        
    }
}

- (size_t)saveToFile {
    
//    NSLog(@"start save file");
    if (isDirty==NO) {
        return -1;
    }
    
    FILE *fp = fopen([self buildFullPath], "w+");
    if (NULL == fp) {
        NSLog(@"AIFUDAO:MpPage:writeWithSrc:cannot open file [%s] for writing.", [self buildFullPath]);
        return 0;
    }
    
    size_t nwrite = fwrite(data, 1, datalenth, fp);
    
    fclose(fp);
    
    if (nwrite != datalenth) {
        NSLog(@"AIFUDAO:MpPage:writeWithSrc:invalid data from file [%s].", [self buildFullPath]);
    }
    
    return nwrite;
    
}

-(void) loadFromFile{
    
    isLoading=YES;
   
    int width=self.frame.size.width;
    int height=self.frame.size.height;
//    int height = [PageContainer getPage_Height];
        
    if (datalenth<=0||data==NULL) {
        datalenth=sizeof(unsigned char)*width*height*4;
        data=malloc(datalenth);
    }
    
//    NSLog(@"datalength:%zu,%zu",datalenth,sizeof(unsigned char));
    
    provider=CGDataProviderCreateWithData(data, data, datalenth, ContentReleaseCallBack);
    
    mContent=CGImageCreate(width, height, 8, 32, 4*width, 
                           CGColorSpaceCreateDeviceRGB(), kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast, 
                           provider, NULL, true, kCGRenderingIntentDefault);
    
    if(mContent==nil){
        NSLog(@"can not creat Content");
    }
    
    mContext = CGBitmapContextCreate(data, CGImageGetWidth(mContent), CGImageGetHeight(mContent), 
                                     CGImageGetBitsPerComponent(mContent), CGImageGetBytesPerRow(mContent), 
                                     CGImageGetColorSpace(mContent), CGImageGetBitmapInfo(mContent));
    
    if(mContext==nil){
        NSLog(@"can not create context");
    }
    
    NSFileManager *fileManager = [NSFileManager defaultManager];
   
    if([fileManager fileExistsAtPath:[NSString stringWithFormat:@"%s",[self buildFullPath]]]){
        
        FILE *fp = fopen([self buildFullPath], "r");
        if (NULL == fp) {
            NSLog(@"AIFUDAO:MpPage:ReadToDest:cannot open file [%s] for reading.", [self buildFullPath]);
        }
        
        size_t nread = fread(data, 1, datalenth, fp);
        
        fclose(fp);
        
        if (nread != datalenth) {
            NSLog(@"AIFUDAO:MpPage:ReadToDest:invalid data from file [%s].datalenth[%zu],nread[%zu]", [self buildFullPath],datalenth,nread);
        }

    }
//    else{
//        CGContextSetFillColorWithColor(mContext, [UIColor clearColor].CGColor);
//        CGContextFillRect(mContext, CGRectMake(0, 0, CGImageGetWidth(mContent), CGImageGetHeight(mContent)));        
//    }
    
    CGContextSetLineJoin(mContext, kCGLineJoinRound);
    CGContextSetLineCap(mContext, kCGLineCapRound);
    CGContextSetStrokeColorWithColor(mContext, [DCGlobal localColor].CGColor);
    CGContextSetLineWidth(mContext, 2);
    
//    [self drawHoldPath];
    
    isLoading=NO;
    
    [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:YES];
    
}



-(const char *) buildFileName{

//    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//    NSString *documentsDirectory = [paths objectAtIndex:0];

    NSString *filename = [NSString stringWithFormat:@"page_%d",[self pageNum]];
    return [filename cStringUsingEncoding:NSASCIIStringEncoding];
}

-(const char *) buildFullPath{
    
    snprintf(name, sizeof(name) - 1, "%s/%s", [@"path" cStringUsingEncoding:NSASCIIStringEncoding], [self buildFileName]);
    
    return name;
    
}

//if you did not use the PageContentOperator to save.you should release the saver yourself.
//-(BOOL)operate:(int)operate_type{
//    
//    if(operate_type==OPERATE_TYPE_LOAD){
//        [self loadFromFile];
//    }else if(operate_type==OPERATE_TYPE_SAVE){
//        [self saveToFile];
//    }
//    
//    return YES;
//}

- (void)dealloc
{
    CGDataProviderRelease(provider);
    CGImageRelease(mContent);
    CGContextRelease(mContext);
    
    [super dealloc];
}



@end
